#ifndef _AES_H_
#define _AES_H_

#include "stdint.h"
#include "string.h"
#include "stdbool.h"

#define BLOCKSIZE                                  16


#define LOAD32H(x, y)                                                             \
  do                                                                              \
  {                                                                               \
    (x) = ((uint32_t)((y)[0] & 0xff) << 24) | ((uint32_t)((y)[1] & 0xff) << 16) | \
          ((uint32_t)((y)[2] & 0xff) << 8) | ((uint32_t)((y)[3] & 0xff));         \
  } while (0)

#define STORE32H(x, y)                      \
  do                                        \
  {                                         \
    (y)[0] = (uint8_t)(((x) >> 24) & 0xff); \
    (y)[1] = (uint8_t)(((x) >> 16) & 0xff); \
    (y)[2] = (uint8_t)(((x) >> 8) & 0xff);  \
    (y)[3] = (uint8_t)((x) & 0xff);         \
  } while (0)

#define BYTE(x, n) (((x) >> (8 * (n))) & 0xff)

#define MIX(x) (((S[BYTE(x, 2)] << 24) & 0xff000000) ^ ((S[BYTE(x, 1)] << 16) & 0xff0000) ^ \
                ((S[BYTE(x, 0)] << 8) & 0xff00) ^ (S[BYTE(x, 3)] & 0xff))

#define ROF32(x, n) (((x) << (n)) | ((x) >> (32 - (n))))

#define ROR32(x, n) (((x) >> (n)) | ((x) << (32 - (n))))

typedef struct
{
  uint32_t eK[44], dK[44];
  int Nr;                  
} AesKey;

/**
 * @brief AES(ECB)加密
 * 
 * @param pKeyValue - 密钥
 * @param KeyLen    - 密钥长度
 * @param pDataIn   - 待加密的数据流
 * @param pDataOut  - 加密后的数据流
 * @param DataSize  - 加密数据长度
 * @return bool     - 加密状态（true: 成功 false: 失败）
 */
bool AesEcbEncrypt(const uint8_t *pKeyValue, uint32_t KeyLen, const uint8_t *pDataIn, uint8_t *pDataOut, uint32_t DataSize);

/**
 * @brief AES(ECB)解密
 * 
 * @param pKeyValue - 密钥
 * @param KeyLen    - 密钥长度
 * @param pDataIn   - 待解密的数据流
 * @param pDataOut  - 解密后的数据流
 * @param DataSize  - 解密数据长度
 * @return bool     - 解密状态（true: 成功 false: 失败）
 */
bool AesEcbDecrypt(const uint8_t *pKeyValue, uint32_t KeyLen, const uint8_t *pDataIn, uint8_t *pDataOut, uint32_t DataSize);

#endif
